package gomat

//#cgo CFLAGS: -O3 
//#cgo LDFLAGS:  -llapacke -lcblas
//#include <stdlib.h>
//#include <cblas.h>
//#include <lapacke.h>
import "C"

func SolveLinearEquations (size int, mat []float64, nrhs int, b []float64) int {
      if size <= 0 {return 0}

	var ipiv []C.int = make ([]C.int, size)
	res := C.LAPACKE_dgesv (C.int(C.LAPACK_COL_MAJOR), C.int(size), C.int(nrhs), (*C.double)(&mat[0]), C.int(size), &ipiv[0], (*C.double)(&b[0]), C.int(size))
	return int(res)
}

func MatVec (size int, mat []float64, x []float64, y[]float64) {
      if size <= 0 {return}

	C.cblas_dgemv (C.CBLAS_LAYOUT(C.CblasColMajor), C.CBLAS_TRANSPOSE(C.CblasNoTrans), 
	C.int(size), C.int(size), C.double(1.0), (*C.double)(&mat[0]), C.int(size), (*C.double)(&x[0]), C.int(1), 
	C.double(0.0), (*C.double)(&y[0]), C.int(1))
}

func MatTransVec (size int, mat []float64, x []float64, y[]float64) {
      if size <= 0 {return}
	C.cblas_dgemv (C.CBLAS_LAYOUT(C.CblasColMajor), C.CBLAS_TRANSPOSE(C.CblasTrans), 
	C.int(size), C.int(size), C.double(1.0), (*C.double)(&mat[0]), C.int(size), (*C.double)(&x[0]), C.int(1), 
	C.double(0.0), (*C.double)(&y[0]), C.int(1))
}

func MatMat (m, n, k int, a []float64, b []float64, c []float64) {
      if m <= 0 || n <= 0 || k <= 0 {return}
      C.cblas_dgemm (C.CBLAS_LAYOUT(C.CblasColMajor), C.CBLAS_TRANSPOSE(C.CblasNoTrans), C.CBLAS_TRANSPOSE(C.CblasNoTrans), C.int(m), C.int(n), C.int(k), 
      C.double(1.0), (*C.double)(&a[0]), C.int(m), (*C.double)(&b[0]), C.int(k), C.double(0.0), (*C.double)(&c[0]), C.int(m))
}

func MatTransMat (m, n, k int, a []float64, b []float64, c []float64) {
      if m <= 0 || n <= 0 || k <= 0 {return}
      C.cblas_dgemm (C.CBLAS_LAYOUT(C.CblasColMajor), C.CBLAS_TRANSPOSE(C.CblasTrans), C.CBLAS_TRANSPOSE(C.CblasNoTrans), C.int(m), C.int(n), C.int(k), 
      C.double(1.0), (*C.double)(&a[0]), C.int(m), (*C.double)(&b[0]), C.int(k), C.double(0.0), (*C.double)(&c[0]), C.int(m))
}

